package com.ruoyi.test.selenium;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.fastjson.JSON;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.test.excel.EasyExcelTools;
import com.ruoyi.test.excel.ExcelDTO;
import com.ruoyi.test.excel.ExcelListener;
import com.ruoyi.test.geetest.GeetsSolveTools;
import com.ruoyi.test.geetest.MoveEntity;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@SuppressWarnings("ALL")
@Service("com.ruoyi.test.selenium.AutoDealWork")
public class AutoDealWork {
    private static final Logger LOGGER = LoggerFactory.getLogger(AutoDealWork.class);
    //存放辅助人工错误的信息列表
    public static List<ExcelDTO> WORK_DATA_ERROR_RESULT = new ArrayList<ExcelDTO>();

    //开始遍历处距离左边的距离
    private  int GEETEST_WIDTH_START_POSTION = 82;
    private static ChromeDriver driver = null;

    @Value("${AUTO_KNOW:NO}")
    private String autoknow;

    public  String autoKnow(){
        String result ="";
        try {
            //鼠标hover出现验证码
            WebElement showImg = driver.findElement(By.cssSelector(".gt_slider_knob.gt_show"));
            WebElement imgHiden = driver.findElement(By.cssSelector(".gt_widget.gt_hide"));
            //driver.executeScript("arguments[0].setAttribute('title','20170718');",imgHiden);
            //driver.executeScript("arguments[0].classList.add(\"gt_show\");",imgHiden);
            Actions actions = new Actions(driver);
            //刷新验证码 gt_refresh_button
            WebElement refresh = driver.findElement(By.cssSelector(".gt_refresh_button"));
            //1获取原图
            actions.moveToElement(showImg).perform();
            Thread.sleep(1 * 1000);
            GeetsSolveTools.obtainOriginalImg(driver,"//*[@id=\"embed-captcha\"]/div/div[1]/div[2]/div[1]");
            //2获取待补全的图
            showImg.click();
            Thread.sleep(2 * 1000);
            actions.moveToElement(showImg).perform();
            GeetsSolveTools.obtainSliderImg(driver,"//*[@id=\"embed-captcha\"]/div/div[1]/div[2]/div[1]");

            //开始计算缺口位置、移动方格至指定位置
            String okXpath = "//div[@class='gt_ajax_tip gt_success']";
            int tryCount = 60;
            calAndMove(showImg,okXpath,tryCount);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //driver.quit();
            System.out.println("===end===");
        }
        return result;
    }

    /**
     * 计算一次 多次尝试 移动
     * @param showImg
     * @param okXpath
     * @param tryCount
     */
    private void calAndMove(WebElement showImg,String okXpath,int tryCount){
        int moveDistance = 5;
        List<MoveEntity> list = null;
        for(int i = 0 ;i < tryCount ;i ++){
            Actions tmp = new Actions(driver);
            tmp.clickAndHold(showImg).perform();
            if(i == 0){
                //计算待移动的位置
                moveDistance = GeetsSolveTools.calcMoveDistance(GEETEST_WIDTH_START_POSTION);
                list = GeetsSolveTools.getMoveEntity(moveDistance);
                LOGGER.info("====auto calcMoveDistance=====================moveDistance:{}",moveDistance);
            }
            System.out.println(i+",===test===moveDistance:"+moveDistance);
            GeetsSolveTools.moveSmallImg(tmp,list, i);
            //移动到指定位置释放鼠标
            tmp.release(showImg).perform();
            try{
                //判断第i 次自动验证结果 是否出现成功的图标
                if(driver.findElement(By.xpath(okXpath)) != null){
                    LOGGER.info("====auto good=====================i:{}",i);
                    break;
                }
            }catch (Exception e2){

            }
        }
    }
    public  String login(String username, String password) throws Exception {
        String result ="";
        driver.manage().window().setSize(new Dimension(1024, 768));
        driver.get("http://www.hebscztxyxx.gov.cn/notice/user/popup_login");
        //切换tab
        WebElement sw = driver.findElement(By.xpath("//*[@id=\"nav\"]/li[2]/a"));
        sw.click();
        Thread.sleep(1 * 1000);
        WebElement mobile = driver.findElement(By.name("loginName"));
        mobile.sendKeys(username);
        WebElement pass = driver.findElement(By.id("loginPswInput"));
        pass.sendKeys(password);
        //自动识别
        if("YES".equals(autoknow)){
            autoKnow();
        }

        Actions actions = new Actions(driver);
        //鼠标hover出现验证码
        WebElement showImg = driver.findElement(By.cssSelector(".gt_slider_knob.gt_show"));
        actions.moveToElement(showImg).perform();

        //等待直到人工完成验证码的识别
        WebDriverWait wait = new WebDriverWait(driver, 10 * 3); // 最多等60秒
        wait.until(new ExpectedCondition<WebElement>() {
            @Override
            public WebElement apply(WebDriver d) {
                return d.findElement(By.xpath("//div[@class='gt_ajax_tip gt_success']"));
            }
        });
        //提交
        driver.findElement(By.id("btn_sign_normal")).click();
        return result;
    }

    /**
     * 设置新密码
     * @param pwd
     * @param nowPwd
     */
    public void setNewPwd(String nowPwd, String newPwd){
        String pwdText = driver.findElement(By.xpath("//*[@id=\"nav2\"]/li[1]")).getText();
        if("设置新密码".equals(pwdText)){
            driver.findElement(By.id("oldPassword")).sendKeys(nowPwd);
            driver.findElement(By.id("password")).sendKeys(newPwd);
            driver.findElement(By.id("confirmPassword")).sendKeys(newPwd);
            driver.findElement(By.id("btn_sign")).click();
        }
    }

    public  void backIndex(){
        try{
            //如果存在密码修改成功的图片
            String img = driver.findElement(By.xpath("//*[@id=\"wrap1\"]/div[5]/div/div/img")).getAttribute("src");
            if(img.contains("ok.gif")){
                //点击返回首页 再次登录
                driver.findElement(By.xpath("//*[@id=\"wrap1\"]/div[5]/div/div/a")).click();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public  String concatCookie(WebDriver driver) {
        Set<Cookie> cookieSet = driver.manage().getCookies();
        StringBuilder sb = new StringBuilder();
        for (Cookie cookie : cookieSet) {
            sb.append(cookie.getName() + "=" + cookie.getValue() + ";");
        }
        String result = sb.toString();
        return result;
    }

    /**
     * 阅读说明
     * @param data
     * @throws Exception
     */
    private void readInfo(ExcelDTO data) throws Exception {
        WebElement yr = driver.findElement(By.xpath("//*[@id=\"reporthomediv\"]/div/ul/li[1]/a"));
        if(yr.getText().contains("报告填写")){
            yr.click();
        }
        Thread.sleep(3 *1000);
        driver.findElement(By.id("dialog-popnote"));
        // 进入 id 叫frameA 的 iframe
        driver.switchTo().frame("dialog-popnote");
        //我已阅读以上填报须知
        driver.findElement(By.id("flag")).click();
        //确认 按钮 关闭弹窗层
        driver.findElement(By.id("closeB1")).click();
        // 回到主窗口
        driver.switchTo().defaultContent();
    }

    /**
     * 填写个体基本信息
     * @param data
     */
    private void writeBaseInfo(ExcelDTO data) throws Exception {
        //个体基本信息 //*[@id="reportForm"]/div[1]/dl/dt[1]
        //联系电话 rptAnnlPe.tel
        String tel = data.getUphone().split(",")[0];
        WebElement tmpEl = driver.findElement(By.xpath("//*[@id=\"reportForm\"]/div[2]/div[1]/div/div[2]/table/tbody/tr[3]/td[2]/input"));
        tmpEl.clear();
        tmpEl.sendKeys(tel);
        //资金数额 rptAnnlPe.fundAm
        String amo = data.getMoney();
        tmpEl = driver.findElement(By.name("rptAnnlPe.fundAm"));
        tmpEl.clear();
        tmpEl.sendKeys(amo);
        //从业人数 rptAnnlEmployee.empNum
        tmpEl=driver.findElement(By.id("input-03"));
        tmpEl.clear();
        tmpEl.sendKeys(String.valueOf(RandomUtils.nextInt(1, 7)));

        tmpEl = driver.findElement(By.xpath("//*[@id=\"reportForm\"]/div[2]/div[1]/div/div[2]/table/tbody/tr[3]/td[2]/input"));
        tmpEl.clear();
        tmpEl.sendKeys(tel);
        //是否有网站或网店
        List<WebElement> yesNo = driver.findElements(By.name("rptAnnlBasic.hasWebsite"));
        for(WebElement tmp: yesNo){
            String vl = tmp.getAttribute("value");
            if("0".equals(vl)){
                tmp.click();
            }
        }
        //保存按钮
        driver.findElement(By.xpath("//*[@id=\"reportForm\"]/div[2]/div[1]/div/div[2]/ul/li[1]/input")).click();
        Thread.sleep(2 *1000);
        Alert yourSelect = driver.switchTo().alert();
        yourSelect.accept();
    }

    /**
     * 资产状况
     * @param data
     * @throws Exception
     */
    private void writeAssets(ExcelDTO data) throws Exception {
        //点击资产状况信息
        driver.findElement(By.xpath("//*[@id=\"reportForm\"]/div[1]/dl/dt[4]")).click();
        Thread.sleep(1 * 1000);
        //营业额或营业收入 rptAnnlRun.vendInc
        WebElement tmpEl =driver.findElement(By.name("rptAnnlRun.vendInc"));
        tmpEl.clear();
        if(StringUtils.isEmpty(data.getVendInc())){
            tmpEl.sendKeys(String.valueOf(RandomUtils.nextInt(2, 10)));
        }
        //纳税总额
        tmpEl =driver.findElement(By.name("rptAnnlRun.ratGro"));
        tmpEl.clear();
        if(StringUtils.isEmpty(data.getRatGro())){
            tmpEl.sendKeys(String.valueOf(RandomUtils.nextInt(2, 10)));
        }

        //是否公示 rptAnnlRun.vendIncSign
        List<WebElement> yesNo = driver.findElements(By.name("rptAnnlRun.vendIncSign"));
        for(WebElement tmp: yesNo){
            String vl = tmp.getAttribute("value");
            if("0".equals(vl)){
                tmp.click();
            }
        }

        yesNo = driver.findElements(By.name("rptAnnlRun.ratGroSign"));
        for(WebElement tmp: yesNo){
            String vl = tmp.getAttribute("value");
            if("0".equals(vl)){
                tmp.click();
            }
        }

        //保存按钮
        driver.findElement(By.xpath("//*[@id=\"reportForm\"]/div[2]/div[4]/div/div[2]/ul/li[1]/input")).click();
        Thread.sleep(2 *1000);
        Alert yourSelect = driver.switchTo().alert();
        yourSelect.accept();
    }

    /**
     * 党建信息
     * @param data
     * @throws Exception
     */
    private void writeParty(ExcelDTO data) throws Exception {
        //点击资产状况信息
        driver.findElement(By.xpath("//*[@id=\"reportForm\"]/div[1]/dl/dt[5]")).click();
        Thread.sleep(1 * 1000);
        //营业额或营业收入 rptAnnlRun.vendInc
        WebElement tmpEl =driver.findElement(By.name("rptAnnlParty.partyNum"));
        tmpEl.clear();
        tmpEl.sendKeys("0");
        //保存按钮
        driver.findElement(By.xpath("//*[@id=\"reportForm\"]/div[2]/div[5]/div/div[2]/ul/li[1]/input")).click();
        Thread.sleep(2 *1000);
        Alert yourSelect = driver.switchTo().alert();
        yourSelect.accept();
    }

    /**
     * 特种设备信息
     * @param data
     * @throws Exception
     */
    private void writeSpeInfo(ExcelDTO data) throws Exception {
        //点击资产状况信息
        driver.findElement(By.xpath("//*[@id=\"reportForm\"]/div[1]/dl/dt[6]")).click();
        Thread.sleep(1 * 1000);
        //营业额或营业收入 rptAnnlRun.vendInc
        WebElement tmpEl = driver.findElement(By.name("rptAnnlSpeEq.speEqValid"));
        tmpEl.clear();
        tmpEl.sendKeys("0");

        tmpEl = driver.findElement(By.name("rptAnnlSpeEq.speEqUsage"));
        tmpEl.clear();
        tmpEl.sendKeys("0");
        //确认
        driver.findElement(By.xpath("//*[@id=\"reportForm\"]/div[2]/div[6]/div/div[3]/li[1]/input")).click();
        Thread.sleep(2 *1000);
        Alert yourSelect = driver.switchTo().alert();
        yourSelect.accept();
    }
    /**
     * 填写报告
     * @param dataList
     * @throws Exception
     */
    public void writeReport(List<ExcelDTO> dataList) {
        if(driver == null){
            driver = new ChromeDriver();
        }
        for(int k = 0;k < dataList.size(); k++ ) {
            ExcelDTO data = dataList.get(k);
            try {
                login(data.getNo(),data.getUid().trim().substring(12));
                Thread.sleep(1 * 1000);
                //跳转填写报告页面
                driver.navigate().to("http://www.hebscztxyxx.gov.cn/notice/report/home");
            } catch (Exception e) {
                data.setAremark(data.getAremark()+"登录失败");
                LOGGER.error(JSON.toJSONString(data.toString()));
                //如果有错误描述信息则放入此list
                WORK_DATA_ERROR_RESULT.add(data);
                LOGGER.error(e.getMessage(),e);
                continue;
            }

            try {
                Thread.sleep(1 * 1000);
                readInfo(data);
            } catch (Exception e) {
                data.setAremark(data.getAremark()+"阅读填写报告失败");
                LOGGER.error(JSON.toJSONString(data.toString()));
                WORK_DATA_ERROR_RESULT.add(data);
                LOGGER.error(e.getMessage(),e);
                continue;
            }
            try {
                Thread.sleep(1 * 1000);
                writeBaseInfo(data);
            } catch (Exception e) {
                data.setAremark(data.getAremark()+"填写个体基本信息失败");
                LOGGER.error(JSON.toJSONString(data.toString()));
                WORK_DATA_ERROR_RESULT.add(data);
                LOGGER.error(e.getMessage(),e);
                continue;
            }
            try{
                Thread.sleep(1 * 1000);
                //资产状况信息 //*[@id="reportForm"]/div[1]/dl/dt[4]
                writeAssets(data);
            }catch (Exception e){
                data.setAremark(data.getAremark()+"填写资产状况信息失败");
                LOGGER.error(JSON.toJSONString(data.toString()));
                WORK_DATA_ERROR_RESULT.add(data);
                LOGGER.error(e.getMessage(),e);
                continue;
            }

            try{
                Thread.sleep(1 * 1000);
                //党建信息
                writeParty(data);
            }catch (Exception e){
                data.setAremark(data.getAremark()+"填写党建信息失败");
                LOGGER.error(JSON.toJSONString(data.toString()));
                WORK_DATA_ERROR_RESULT.add(data);
                LOGGER.error(e.getMessage(),e);
                continue;
            }

            try{
                Thread.sleep(1 * 1000);
                //特种设备信息
                writeSpeInfo(data);
            }catch (Exception e){
                data.setAremark(data.getAremark()+"填写特种设备信息失败");
                LOGGER.error(JSON.toJSONString(data.toString()));
                WORK_DATA_ERROR_RESULT.add(data);
                LOGGER.error(e.getMessage(),e);
                continue;
            }

        }

        driver.executeScript("alert('任务已经处理完成，请关闭浏览器');");
    }

    /**
     * 开启新密码设置
     * @param dataList
     */
    public void startNewPwd(List<ExcelDTO> dataList){
        if(driver == null){
            driver = new ChromeDriver();
        }
        //批量处理
        for(int k = 0;k < dataList.size(); k++ ){
            ExcelDTO data = dataList.get(k);
            System.out.println(k+"===="+data.toString());
            //登录
            String pwd = data.getUid().trim().substring(12);
            String newPwd = pwd +"aB";
            try {
                login(data.getNo(),pwd);
            } catch (Exception e) {
                data.setAremark(data.getAremark()+"登录失败");
                LOGGER.error(JSON.toJSONString(data.toString()));
                WORK_DATA_ERROR_RESULT.add(data);
                LOGGER.error(e.getMessage(),e);
                continue;
            }
            try {//设置新密码
                Thread.sleep(1 * 1000);
                setNewPwd(pwd,newPwd);
            } catch (Exception e) {
                data.setAremark(data.getAremark()+"设置新密码失败");
                LOGGER.error(JSON.toJSONString(data.toString()),e);
                WORK_DATA_ERROR_RESULT.add(data);
                LOGGER.error(e.getMessage(),e);
                continue;
            }

        }

    }

    static {
        System.setProperty("webdriver.chrome.driver", "D:\\project-auto\\chromedriver.exe");
    }
    public static void main(String[] args){
        AutoDealWork work = new AutoDealWork();
        //读取EXCEL
        String filePath = "D:\\home\\tmp1.xls";
        //List<Object> objs = EasyExcelTools.readLessThan1000RowBySheet(filePath,null);
        //objs.forEach(System.out::println);
       /* for(int i =0;i < 10; i ++){
            String username = "92130184MA0EG81G64";
            String pwd = "130184198512194530".substring(12);
            String newPwd = pwd +"aB";
            try {
                work.login(username,pwd);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }*/
        //setNewPwd(pwd,newPwd);

        //login(username,newPwd);
        //writeReport();

        //解析Excel
        List<ExcelDTO> list = EasyExcelTools.parseExcel(filePath);
        //批量设置密码
        //work.startNewPwd(list);
        //批量填写报告 http://www.hebscztxyxx.gov.cn/notice/report/home
        work.writeReport(list);
    }


}
